from uiautomation import Control
from penguin import desk, auto, logging

class Window:
    """此类型实例代表应用程序中的窗口。

    Attributes:
        name (str): 
        desc (str):
        class_name (str):
        next_level_window (Window):
        parent (Window):
        window (TopLevel):
    """
    def __init__(self, name: str, desc: str, class_name: str, parent = None):
        """初始化实例。

        Args:
            name (str): 窗口名称。
            class_name (str): 窗口在UIautomation系统中类名。
            parent (Window): 父级控件。
        """
        self.name: str = name
        self.desc: str = desc
        self.class_name: str = class_name
        self.next_level_window: Window = None
        self.parent = parent
        self.window = desk.WindowControl(searchDepth = 1, ClassName = self.class_name)
        logging.info('以 %s 为名称初始化 %s 。' % (self.name, self.desc))

    def conform_features(self) -> bool:
        """确认窗口特征。
        
        Returns:
            bool: 确认成功为True， 失败为False。
        """
        return True

    def is_on_desk(self) -> bool:
        """判断窗口是否显示在系统桌面上。

        Returns:
            bool: 显示成功为True， 失败为False。
        """
        try:
            isMinimize = self.window.IsMinimize()
            # 判断当前窗口是否以最小化，如果窗口为最小化模式则不认为窗口已经显示在系统桌面。
            if not isMinimize:
                # 对窗口特征进行确认。
                is_confirmed = self.conform_features()
                if is_confirmed:
                    logging.debug('以 %s 为名称的 %s 已经显示在系统桌面。' % (self.name, self.desc))
                else:
                    logging.debug('以 %s 为名称的 %s 没有显示在系统桌面。' % (self.name, self.desc))
                return is_confirmed
            else:
                logging.debug('以 %s 为名称的 %s 没有显示在最上层。' % (self.name, self.desc))
                return False
        except LookupError as e:
            logging.warning('以 %s 为名称的 %s 没有显示在系统桌面。' % (self.name, self.desc))
            return False
        
    def find_entrance(self, name: str) -> Control:
        """根据名称查找入口控件。

        Args:
            name (str): 要查找的入口控件名称。
        Returns:
            Control: 可点击的入口控件。
        """
        pass

    def set_focus(self):
        self.window.SetFocus()
        
    def open_new_window(self, name:str, class_name:str, class_type):
        """
        Args:
            name (str):
            class_name (str):
            class_type (Class):
        returns:
            Window | None:
        """
        new_window : Window = class_type(name, class_name, self)
        logging.info('查找以 %s 命名的 %s 入口 。' % (name, new_window.desc))
        entrance : Control = self.find_entrance(name)
        if entrance != None:
            entrance.Click()
            logging.info('打开以 %s 命名的 %s。' % (name, new_window.desc))
            # 检查公众号窗口打开是否正常，没有正常打开尝试重新点击打开，共尝试3次。
            for i in range(3):
                logging.info('检查以 %s 命名的 %s 是否显示在系统桌面。' % (name, new_window.desc))
                if new_window.is_on_desk():
                    logging.info('以 %s 命名的 %s 已经显示在系统桌面。' % (name, new_window.desc))
                    self.next_level_window = new_window
                    return self.next_level_window
                else:
                    logging.warning('第 %d 次重新打开以 %s 命名的 %s 。' % (i+1, name, new_window.desc))
                    entrance.Click()
        else:
            logging.info('没有找到以 %s 命名的 %s 。' % (name, new_window.desc))
            return None
        logging.error('没有正常打开以 %s 命名的 %s 。' % (name, new_window.desc))
        return None

    def close(self):
        """关闭窗口。
        """        
        # 如果本窗口实例有下一级窗口并且下一级窗口显示在桌面，先关闭下一级窗口。
        if not self.next_level_window == None and self.next_level_window.is_on_desk():
            self.next_level_window.close()
        # 如果本窗口实例显示在桌面，使用热键组合方式关闭本窗口。
        if self.is_on_desk():
            self.window.SetFocus()
            auto.SendKeys('{Alt}{F4}')
            logging.info('以 %s 为名称的 %s 已经关闭。' % (self.name, self.desc))
